package com.dc.schedule.client.convertor;

import com.dc.schedule.api.model.SocketMessage;
import com.dc.schedule.api.model.SocketMessageType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;
import java.util.TimeZone;

@Slf4j
@RequiredArgsConstructor
public class JacksonClientMessageConvertorImpl implements ClientMessageConvertor {
    private final ObjectMapper objectMapper;
    
    public JacksonClientMessageConvertorImpl() {
        objectMapper = new ObjectMapper();
        objectMapper.setTimeZone(TimeZone.getDefault());
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }
    
    /**
     * 字符串转换成对象
     *
     * @param json json数据
     * @return 对象
     */
    @Override
    public SocketMessage decode(String json) {
        final JsonNode jsonNode;
        try {
            jsonNode = objectMapper.readTree(json);
        } catch (JsonProcessingException e) {
            throw new IllegalStateException("读取json失败, json:" + json, e);
        }
        final String messageType = Optional.of(jsonNode).map(e -> e.get("type"))
                                           .map(JsonNode::asText)
                                           .orElse(null);
        
        Class<? extends SocketMessage> messageCls = SocketMessageType.forType(messageType);
        return objectMapper.convertValue(jsonNode, messageCls);
    }
    
    /**
     * 对象转换成 json字符串
     *
     * @param message 对象
     * @return 字符串
     */
    @Override
    public String encode(SocketMessage message) {
        try {
            return objectMapper.writeValueAsString(message);
        } catch (JsonProcessingException e) {
            throw new IllegalStateException("json转换还失败", e);
        }
    }
    
}
